﻿using System;
using System.Windows;
using eWallet.Data.Local;
using System.Windows.Controls;
using eWallet.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography;
using eWallet.Data.Local.eWalletDataSetTableAdapters;

namespace eWallet
{
	/// <summary>
	/// Interaction logic for GroupWindow.xaml
	/// </summary>
	public partial class GroupWindow : Window
	{

		public GroupWindow()
		{
			InitializeComponent();
		}

		public eWalletDataSet.GroupsRow SelectedGroup { get; set; }



		private X509Certificate2 _SelectedCertificate;
		private X509Certificate2 SelectedCertificate
		{
			get { return _SelectedCertificate; }
			set
			{
				_SelectedCertificate = value;
				this.CertificateTextbox.Text = string.Empty;

				this.ViewCertificateButton.IsEnabled = null != value;
				if (null != value)
				{
					this.CertificateTextbox.Text = value.ToString();
				}
			}
		}



		protected override void OnContentRendered(EventArgs e)
		{

			this.NameTextbox.Text = this.SelectedGroup.Name;
			if (!this.SelectedGroup.IsDescriptionNull())
			{
				this.DescriptionTextbox.Text = this.SelectedGroup.Description;
			}

			if (this.SelectedGroup.EncryptionMethod == EncryptionMethod.Password)
			{
				this.EncryptionMethodCombo.SelectedIndex = 0;
			}
			else
			{
				this.EncryptionMethodCombo.SelectedIndex = 1;
				this.CertificateTextbox.Text = this.SelectedGroup.EncryptorDescription;
			}

			base.OnContentRendered(e);
		}



		private EncryptionMethod GetCurrentEncryptionMode()
		{
			ComboBoxItem item = (ComboBoxItem)this.EncryptionMethodCombo.SelectedItem;
			EncryptionMethod method = (EncryptionMethod)Enum.Parse(typeof(EncryptionMethod), (string)item.Tag);
			return method;
		}


		private void OKButton_Click(object sender, RoutedEventArgs e)
		{

			if (string.IsNullOrEmpty(this.NameTextbox.Text) || this.NameTextbox.Text.Trim().Length == 0)
			{
				MessageBox.Show(this, "The group name is required. Please give the group a name.", "Name Missing", MessageBoxButton.OK, MessageBoxImage.Error);
				this.MainTab.SelectedItem = this.GeneralTabItem;
				this.NameTextbox.Focus();

				return;
			}

			if (this.GetCurrentEncryptionMode() == EncryptionMethod.Password)
			{
				if (!string.Equals(this.PasswordTextbox.Password, this.RetypePasswordTextbox.Password, StringComparison.Ordinal))
				{
					this.PasswordTextbox.Password = string.Empty;
					this.RetypePasswordTextbox.Password = string.Empty;
					MessageBox.Show(this, "The passwords you entered do not match. Please retype the passwords exactly the same way. Note also that passwords are case sensitive.", "Password Mismatch", MessageBoxButton.OK, MessageBoxImage.Error);
					this.MainTab.SelectedItem = this.EncryptionTabItem;
					this.PasswordTextbox.Focus();

					return;
				}

				if (string.IsNullOrEmpty(this.PasswordTextbox.Password) || this.PasswordTextbox.Password.Trim().Length == 0)
				{
					MessageBox.Show(this, "The password cannot be empty. Please specify a password for the group or select another encryption method.", "Empty Password", MessageBoxButton.OK, MessageBoxImage.Error);
					this.MainTab.SelectedItem = this.EncryptionTabItem;
					this.PasswordTextbox.Focus();

					return;
				}

			}
			if (this.GetCurrentEncryptionMode() == EncryptionMethod.Certificate)
			{
				if (null == this.SelectedCertificate)
				{
					MessageBox.Show(this, "No certificate was selected. Please select a certificate or select another encryption method.", "Certificate Missing", MessageBoxButton.OK, MessageBoxImage.Error);
					this.MainTab.SelectedItem = this.EncryptionTabItem;
					return;
				}
			}

			// If we get this far, then all validations have succeeded so we go ahead
			// and save the group.
			this.SelectedGroup.Name = this.NameTextbox.Text;
			this.SelectedGroup.Description = this.DescriptionTextbox.Text;
			this.SelectedGroup.EncryptionMethod = this.GetCurrentEncryptionMode();
			this.SelectedGroup.LastModified = DateTime.UtcNow;
			this.SelectedGroup.LastModifiedBy = string.Format(@"{0}\{1}", Environment.UserDomainName, Environment.UserName);
			
			switch (this.SelectedGroup.EncryptionMethod)
			{
				case EncryptionMethod.Password:
					PasswordCryptoModule pwdModule = new PasswordCryptoModule(this.PasswordTextbox.Password);
					this.SelectedGroup.EncryptedKey = this.SelectedGroup.CreateEncryptedKey(pwdModule);
					this.SelectedGroup.EncryptorDescription = pwdModule.GetDescription();
					break;

				case EncryptionMethod.Certificate:
					CertificationCryptoModule certModule = new CertificationCryptoModule(this.SelectedCertificate);
					this.SelectedGroup.EncryptedKey = this.SelectedGroup.CreateEncryptedKey(certModule);
					this.SelectedGroup.EncryptorDescription = certModule.GetDescription();
					break;
			}

			this.DialogResult = true;
			this.Close();
		}

		private void CancelButton_Click(object sender, RoutedEventArgs e)
		{
			this.DialogResult = false;
			this.Close();
		}

		private void EncryptionMethodCombo_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
		{
			this.PasswordEncryptionGroup.Visibility = Visibility.Collapsed;
			this.CertificateEncryptionGroup.Visibility = Visibility.Collapsed;

			switch (this.GetCurrentEncryptionMode())
			{
				case EncryptionMethod.Password:
					this.PasswordEncryptionGroup.Visibility = Visibility.Visible;
					break;

				case EncryptionMethod.Certificate:
					this.CertificateEncryptionGroup.Visibility = Visibility.Visible;
					break;

				default:
					MessageBox.Show(this, "The selected encryption method is not supported.", "Unsupported Method", MessageBoxButton.OK, MessageBoxImage.Warning);
					break;
			}
		}

		private void GeneratePasswordButton_Click(object sender, RoutedEventArgs e)
		{
			MessageBox.Show("Not Implemented.");
		}

		private void BrowseCertificateButton_Click(object sender, RoutedEventArgs e)
		{
			MessageBox.Show("Not Implemented.");
		}
	}
}
